import os
import base64
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QFrame, QHBoxLayout, QLabel, QPushButton, QLineEdit, \
    QScrollArea, QGridLayout, QDialog, QFormLayout, QDoubleSpinBox, QSpinBox, QTextEdit, QFileDialog, QMessageBox
from fastApi.database.base import get_db


class ProductCard(QFrame):
    def __init__(self, product_data, parent=None):
        super().__init__(parent)
        self.product_data = product_data
        self.parent_widget = parent
        self.init_ui()
        self.setFixedSize(250, 320)
        self.setFrameStyle(QFrame.Box)
        self.setStyleSheet("""
            QFrame {
                background-color: white;
                border-radius: 10px;
            }
            QFrame:hover {
                border: 2px solid #ff5f00;
            }
        """)
        self.setCursor(Qt.PointingHandCursor)

    def init_ui(self):
        icon = QIcon('./images/购物.png')
        self.setWindowIcon(icon)
        mainLayout = QVBoxLayout()

        self.image_label = QLabel()
        self.image_label.setFixedSize(220, 150)
        self.image_label.setAlignment(Qt.AlignCenter)
        self.image_label.setStyleSheet("""
            QLabel {
                border: 2px solid #f9f9f9;
                border-radius: 8px;
                background-color: #f9f9f9;
                color: #999;
                font-size: 12px;
            }
        """)
        self.load_product_image()
        mainLayout.addWidget(self.image_label)

        name_label = QLabel(self.product_data.get('name', '未知商品'))
        name_label.setStyleSheet("""
            QLabel {
                font-family: Arial;
                font-size: 15px;
                font-weight: bold;
                border: 1px solid white;
                margin: 2px 0;
            }
        """)
        name_label.setWordWrap(True)
        name_label.setMaximumHeight(40)
        mainLayout.addWidget(name_label)

        price_label = QLabel(f"¥{self.product_data.get('price', 0):.2f}")
        price_label.setStyleSheet("""
            font-family: Arial;
            font-size: 18px;
            font-weight: bold;
            border: 1px solid white;
            color: red;
            margin: 2px 0;
        """)
        price_label.setMaximumHeight(40)
        mainLayout.addWidget(price_label)

        self.setLayout(mainLayout)

    def load_product_image(self):
        image_base64 = self.product_data.get('image_base64')
        if image_base64:
            try:
                image_data = base64.b64decode(image_base64)
                pixmap = QPixmap()
                pixmap.loadFromData(image_data)
                if not pixmap.isNull():
                    self.image_label.setPixmap(pixmap.scaled(220, 150, Qt.KeepAspectRatio, Qt.SmoothTransformation))
                    self.image_label.setScaledContents(True)
                    return
            except Exception as e:
                print(f"产品 {self.product_data.get('id', 0)} 的 Base64 图片解码失败: {e}")
        self.image_label.setText("暂无图片")

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.show_details()

    def show_details(self):
        detail_dialog = QDialog(self)
        detail_dialog.setWindowTitle(self.product_data.get('name', '商品详情'))
        detail_dialog.resize(400, 500)

        layout = QVBoxLayout()

        image_label = QLabel()
        image_label.setFixedSize(300, 200)
        image_label.setAlignment(Qt.AlignCenter)
        image_base64 = self.product_data.get('image_base64')
        if image_base64:
            try:
                image_data = base64.b64decode(image_base64)
                pixmap = QPixmap()
                pixmap.loadFromData(image_data)
                if not pixmap.isNull():
                    image_label.setPixmap(pixmap.scaled(300, 200, Qt.KeepAspectRatio, Qt.SmoothTransformation))
                    image_label.setScaledContents(False)
            except Exception as e:
                print(f"产品 {self.product_data.get('id', 0)} 的 Base64 图片解码失败: {e}")
                image_label.setText("暂无图片")
        else:
            image_label.setText("暂无图片")
        layout.addWidget(image_label)

        name_label = QLabel(f"名称: {self.product_data.get('name', '未知')}")
        name_label.setStyleSheet("font-size: 16px; font-weight: bold;")
        layout.addWidget(name_label)

        price_label = QLabel(f"价格: ¥{self.product_data.get('price', 0):.2f}")
        price_label.setStyleSheet("font-size: 14px; color: red;")
        layout.addWidget(price_label)

        stock = self.product_data.get('quantity', 0)
        stock_label = QLabel(f"库存: {stock}")
        if stock > 0:
            stock_label.setStyleSheet("color: #27ae60; font-size: 12px;")
        else:
            stock_label.setStyleSheet("color: #e74c3c; font-size: 12px;")
        layout.addWidget(stock_label)

        desc_label = QLabel(f"描述: {self.product_data.get('description', '无描述')}")
        desc_label.setWordWrap(True)
        layout.addWidget(desc_label)

        # Add Edit and Delete buttons
        button_layout = QHBoxLayout()
        edit_button = QPushButton("编辑")
        edit_button.setCursor(Qt.PointingHandCursor)
        edit_button.setStyleSheet("""
            QPushButton {
                background-color: #ff5f00;
                color: white;
                padding: 6px 10px;
                border-radius: 4px;
                font-size: 12px;
            }
        """)
        edit_button.clicked.connect(lambda: self.edit_product(detail_dialog))
        button_layout.addWidget(edit_button)

        delete_button = QPushButton("删除")
        delete_button.setCursor(Qt.PointingHandCursor)
        delete_button.setStyleSheet("""
            QPushButton {
                background-color: #e74c3c;
                color: white;
                padding: 6px 10px;
                border-radius: 4px;
                font-size: 12px;
            }
        """)
        delete_button.clicked.connect(lambda: self.delete_product(detail_dialog))
        button_layout.addWidget(delete_button)

        layout.addLayout(button_layout)
        detail_dialog.setLayout(layout)
        detail_dialog.exec_()

    def edit_product(self, dialog):
        edit_dialog = QDialog(self)
        edit_dialog.setWindowTitle("编辑商品")
        edit_dialog.resize(400, 500)
        layout = QFormLayout()

        name_input = QLineEdit(self.product_data.get('name', ''))
        layout.addRow("商品名称:", name_input)

        price_input = QDoubleSpinBox()
        price_input.setDecimals(2)
        price_input.setMaximum(999999.99)
        price_input.setValue(self.product_data.get('price', 0.0))
        layout.addRow("价格:", price_input)

        quantity_input = QSpinBox()
        quantity_input.setMaximum(9999)
        quantity_input.setValue(self.product_data.get('quantity', 0))
        layout.addRow("库存:", quantity_input)

        description_input = QTextEdit(self.product_data.get('description', ''))
        layout.addRow("描述:", description_input)

        image_label = QLabel("点击上传图片")
        image_label.setStyleSheet("color: #999; font-size: 12px;")
        image_label.setAlignment(Qt.AlignCenter)
        image_label.setFixedSize(200, 100)
        image_path = [None]  # Use list to allow modification in lambda
        if self.product_data.get('image_base64'):
            try:
                image_data = base64.b64decode(self.product_data.get('image_base64'))
                pixmap = QPixmap()
                pixmap.loadFromData(image_data)
                if not pixmap.isNull():
                    image_label.setPixmap(pixmap.scaled(200, 100, Qt.KeepAspectRatio, Qt.SmoothTransformation))
            except Exception as e:
                print(f"产品 {self.product_data.get('id', 0)} 的 Base64 图片解码失败: {e}")
        image_label.mousePressEvent = lambda event: self.upload_image(image_label, image_path)
        layout.addRow("商品图片:", image_label)

        save_button = QPushButton("保存")
        save_button.setStyleSheet("""
            QPushButton {
                background-color: #ff5f00;
                color: white;
                padding: 6px 10px;
                border-radius: 4px;
                font-size: 12px;
            }
        """)
        save_button.clicked.connect(lambda: self.save_edited_product(
            dialog, edit_dialog, name_input.text(), price_input.value(),
            quantity_input.value(), description_input.toPlainText(), image_path[0]
        ))
        layout.addRow(save_button)

        edit_dialog.setLayout(layout)
        edit_dialog.exec_()

    def upload_image(self, image_label, image_path):
        file_dialog = QFileDialog()
        file_path, _ = file_dialog.getOpenFileName(self, "选择图片", "", "Images (*.png *.jpg *.jpeg)")
        if file_path:
            try:
                with open(file_path, "rb") as image_file:
                    pixmap = QPixmap(file_path)
                    if not pixmap.isNull():
                        image_label.setPixmap(pixmap.scaled(200, 100, Qt.KeepAspectRatio, Qt.SmoothTransformation))
                        image_path[0] = file_path
                    else:
                        image_label.setText("图片无效")
            except Exception as e:
                print(f"图片加载失败: {e}")
                image_label.setText("图片加载失败")

    def save_edited_product(self, parent_dialog, edit_dialog, name, price, quantity, description, image_path):
        if not name:
            QMessageBox.warning(self, "错误", "商品名称不能为空")
            return

        # 检查商品名称是否已存在（排除当前商品）
        db = get_db()
        existing_product = db.selectData("SELECT id FROM products WHERE name = ? AND id != ?",
                                         [name, self.product_data['id']])
        if existing_product:
            QMessageBox.warning(self, "错误", "商品名称已存在")
            return

        image_base64 = self.product_data.get('image_base64')  # 保留原有图片
        if image_path:  # 如果上传了新图片，则更新
            try:
                with open(image_path, "rb") as image_file:
                    image_base64 = base64.b64encode(image_file.read()).decode('utf-8')
            except Exception as e:
                print(f"图片转换失败: {e}")
                QMessageBox.warning(self, "错误", f"图片转换失败: {e}")
                return

        db.operation_sql(
            "UPDATE products SET name = ?, description = ?, price = ?, quantity = ?, image_base64 = ? WHERE id = ?",
            [name, description, price, quantity, image_base64, self.product_data['id']]
        )
        db.commit()
        self.parent_widget.load_products()
        edit_dialog.close()
        parent_dialog.close()
        QMessageBox.information(self, "成功", "商品已更新")

    def delete_product(self, dialog):
        reply = QMessageBox.question(self, '确认', '确定要删除此商品吗？',
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            db = get_db()
            db.operation_sql("DELETE FROM products WHERE id = ?", [self.product_data['id']])
            db.commit()
            self.parent_widget.load_products()
            dialog.close()
            QMessageBox.information(self, "成功", "商品已删除")


class ProductManagementWidget(QWidget):
    def __init__(self, parent, login_widget, user_info=None):
        super().__init__()
        self.parent = parent
        self.login_widget = login_widget  # 存储登录窗口实例
        self.user_info = user_info or {}
        self.setWindowTitle("购物商城")
        self.resize(1200, 800)
        self.init_ui()
        self.load_products()

    def init_ui(self):
        icon = QIcon('./images/购物.png')
        self.setWindowIcon(icon)
        mainLayout = QVBoxLayout()
        mainLayout.setContentsMargins(20, 20, 20, 20)
        mainLayout.setSpacing(20)

        self.create_top_bar(mainLayout)
        self.create_searchFrame(mainLayout)
        self.create_productsScrollArea(mainLayout)

        self.setLayout(mainLayout)

    def create_top_bar(self, main_layout):
        topBar = QFrame()
        topBar.setStyleSheet("""
            QFrame {
                background-color: #ff5f00;
                border-radius: 8px;
                padding: 10px;
            }
        """)
        topLayout = QHBoxLayout()

        welcome_label = QLabel()
        welcome_label.setStyleSheet("color: white; font-size: 25px; font-weight: bold; font-family: Microsoft YaHei;")

        add_product_btn = QPushButton("添加商品")
        add_product_btn.setCursor(Qt.PointingHandCursor)
        add_product_btn.setStyleSheet("""
            QPushButton {
                background-color: white;
                color: #ff5f00;
                padding: 10px 20px;
                border-radius: 5px;
                font-size: 14px;
                font-weight: bold;
            }
        """)
        add_product_btn.clicked.connect(self.show_add_product_dialog)

        self.logout_btn = QPushButton("退出")
        self.logout_btn.setCursor(Qt.PointingHandCursor)
        self.logout_btn.setStyleSheet("""
            QPushButton {
                background-color: white;
                color: #ff5f00;
                padding: 10px 20px;
                border-radius: 5px;
                font-size: 14px;
                font-weight: bold;
            }
        """)
        self.logout_btn.clicked.connect(self.logout)
        topLayout.addWidget(welcome_label)
        topLayout.addStretch()
        topLayout.addWidget(add_product_btn)
        topLayout.addWidget(self.logout_btn)

        topBar.setLayout(topLayout)
        main_layout.addWidget(topBar)

    def show_add_product_dialog(self):
        add_dialog = QDialog(self)
        add_dialog.setWindowTitle("添加新商品")
        add_dialog.resize(400, 500)
        layout = QFormLayout()

        name_input = QLineEdit()
        layout.addRow("商品名称:", name_input)

        price_input = QDoubleSpinBox()
        price_input.setDecimals(2)
        price_input.setMaximum(999999.99)
        layout.addRow("价格:", price_input)

        quantity_input = QSpinBox()
        quantity_input.setMaximum(9999)
        layout.addRow("库存:", quantity_input)

        description_input = QTextEdit()
        layout.addRow("描述:", description_input)

        image_label = QLabel("点击上传图片")
        image_label.setStyleSheet("color: #999; font-size: 12px;")
        image_label.setAlignment(Qt.AlignCenter)
        image_label.setFixedSize(200, 100)
        image_path = [None]
        image_label.mousePressEvent = lambda event: self.upload_image(image_label, image_path)
        layout.addRow("商品图片:", image_label)

        save_button = QPushButton("保存")
        save_button.setStyleSheet("""
            QPushButton {
                background-color: #ff5f00;
                color: white;
                padding: 6px 10px;
                border-radius: 4px;
                font-size: 12px;
            }
        """)
        save_button.clicked.connect(lambda: self.save_new_product(
            add_dialog, name_input.text(), price_input.value(),
            quantity_input.value(), description_input.toPlainText(), image_path[0]
        ))
        layout.addRow(save_button)

        add_dialog.setLayout(layout)
        add_dialog.exec_()

    def upload_image(self, image_label, image_path):
        file_dialog = QFileDialog()
        file_path, _ = file_dialog.getOpenFileName(self, "选择图片", "", "Images (*.png *.jpg *.jpeg)")
        if file_path:
            try:
                with open(file_path, "rb") as image_file:
                    pixmap = QPixmap(file_path)
                    if not pixmap.isNull():
                        image_label.setPixmap(pixmap.scaled(200, 100, Qt.KeepAspectRatio, Qt.SmoothTransformation))
                        image_path[0] = file_path
                    else:
                        image_label.setText("图片无效")
            except Exception as e:
                print(f"图片加载失败: {e}")
                image_label.setText("图片加载失败")

    def save_new_product(self, dialog, name, price, quantity, description, image_path):
        if not name:
            QMessageBox.warning(self, "错误", "商品名称不能为空")
            return

        # 检查商品名称是否已存在
        db = get_db()
        existing_product = db.selectData("SELECT id FROM products WHERE name = ?", [name])
        if existing_product:
            QMessageBox.warning(self, "错误", "商品名称已存在")
            return

        image_base64 = None
        if image_path:
            try:
                with open(image_path, "rb") as image_file:
                    image_base64 = base64.b64encode(image_file.read()).decode('utf-8')
            except Exception as e:
                print(f"图片转换失败: {e}")
                QMessageBox.warning(self, "错误", f"图片转换失败: {e}")
                return

        db.operation_sql(
            "INSERT INTO products (name, description, price, quantity, image_base64) VALUES (?, ?, ?, ?, ?)",
            [name, description, price, quantity, image_base64]
        )
        db.commit()
        self.load_products()
        dialog.close()
        QMessageBox.information(self, "成功", "商品已添加")

    def create_searchFrame(self, main_layout):
        searchFrame = QFrame()
        searchFrame.setStyleSheet("""
            background-color: #f8f9fa;
            border-radius: 5px;
            padding: 3px
        """)

        searchLayout = QHBoxLayout()

        self.imageLabel = QLabel(self)
        self.imageLabel.setFixedSize(100, 50)
        self.imageLabel.setPixmap(QPixmap('./images/购物2.png'))
        self.imageLabel.setScaledContents(True)
        searchLayout.addWidget(self.imageLabel)

        self.searchInput = QLineEdit()
        self.searchInput.setPlaceholderText(" 搜索商品...")
        self.searchInput.setStyleSheet("""
            QLineEdit {
                padding: 10px;
                border: 2px solid #ddd;
                border-radius: 10px;
                font-size: 20px;
                background-color: white;
                border-color: #ff5f00;
            }
        """)
        self.searchInput.textChanged.connect(self.filter_products)
        searchLayout.addWidget(self.searchInput)
        searchFrame.setLayout(searchLayout)
        main_layout.addWidget(searchFrame)

    def create_productsScrollArea(self, mainLayout):
        productsScrollArea = QScrollArea()
        productsScrollArea.setWidgetResizable(True)
        productsScrollArea.setStyleSheet("""
            border: 2px solid #ddd;
            background-color: white;
            border-radius: 15px;
        """)

        self.products_container = QWidget()
        self.products_layout = QGridLayout()
        self.products_layout.setSpacing(15)
        self.products_container.setLayout(self.products_layout)

        productsScrollArea.setWidget(self.products_container)
        mainLayout.addWidget(productsScrollArea)

    def filter_products(self):
        search_text = self.searchInput.text().lower()
        self.filtered_product = []

        for product in self.all_products:
            if search_text and search_text not in product['name'].lower():
                continue
            self.filtered_product.append(product)

        self.update_product_display()

    def update_product_display(self):
        for i in reversed(range(self.products_layout.count())):
            child = self.products_layout.itemAt(i).widget()
            if child:
                child.setParent(None)
        row, col = 0, 0
        max_cols = 4

        for product in self.filtered_product:
            card = ProductCard(product, self)
            self.products_layout.addWidget(card, row, col)
            col += 1
            if col >= max_cols:
                col = 0
                row += 1

    def load_products(self):
        db = get_db()
        self.all_products = db.selectData("SELECT * FROM products")
        self.filter_products()

    def logout(self):
        self.close()
        if self.login_widget:
            self.login_widget.clear_inputs()  # 清空输入框
            self.login_widget.show()  # 显示登录窗口
        # 添加关闭 ShopManage 窗口的逻辑
        if hasattr(self, 'parent') and self.parent:
            self.parent.close()  # 关闭 ShopManage 窗口